library(tidyverse, verbose = F)
── Attaching core tidyverse packages ───────────────────────────────────────────────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.4.4     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.1
✔ purrr     1.0.2     ── Conflicts ─────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errorsWarning message:
In readRDS(path) : error al leer desde conexión
source("Funciones.R")

Lectura de Datos

Lo datos corresponde a una matriz 5x5x10. La metadata será X = 1…25 y Z = 1…10 (profundidad), ambos detectores tienen la misma metadata.

##Metadata
Metadata <- data.frame(x = rep(1:100, each = 11), 
                       z = rep(1:11, 100))

Comp.data <- data.frame(muestra = c("ss406", "ss407", "ss408", "ss409", "ss410"), 
                        C = c(0.19,0.50,0.28,0.11,0.39),
                        Mn = c(0.53,0.13,0.64,0.48,0.43),
                        Ni = c(1.69,0.61,4.58,3.14,2.04),
                        Cr = c(2.12,3.00,0.09,1.22,1.72),
                        Mo = c(1.03,0.82,0.14,0.77,0.41),
                        Cu = c(0.32,0.43,0.73,0.23,0.47))

DEMON

data.dir <- "Data/demon/"

wl <- read_tsv(paste(data.dir,"ss406.asc",sep = ""), col_names = F, progress = F, show_col_types = F) %>% 
        .[,1] %>% set_names("wl") %>% rowid_to_column()

## DEMON data
L_Demon <- map(c("ss406.asc","ss407.asc","ss408.asc","ss409.asc","ss410.asc"), 
               ~ read_tsv(paste(data.dir,.x,sep = ""), col_names = F, progress = F, show_col_types = F)) 

L_Demon <- L_Demon %>% set_names(c("ss406","ss407","ss408","ss409","ss410"))  

L_Demon <- L_Demon %>% map(~ .x %>% setNames(c("wl",paste("X", 1:(ncol(.x)-1), sep = ""))))

## elimina shot 1
L_Demon <- L_Demon %>% 
  map(~ .x %>% .[, c(1, which(Metadata$z != 1) + 1)]) ## elimina disparo #1 (limpieza)

g <- L_Demon %>% map(~ data.frame(.x[,1], Int = apply(.x[,2:ncol(.x)], 1, mean))) %>% bind_rows(.id = "id") %>% 
  ggplot(aes(x = wl, y = Int, color = id)) + geom_line() + labs(x = "Wavelength")
g %>% plotly::ggplotly()
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
## Normalizar
izq <- 267.70
der <- 267.75
int <- L_Demon %>% map_dfr(fun.int, izq = izq, der = der)
factor <-  1
int_norm <- int/factor

## acumular
int_norm <- sumar_filas_por_grupos(int_norm, n = 10, wl = F)

## Promediar
int_norm <- cbind(Comp.data, int_norm)
int_norm %>% pivot_longer(X1:X100, values_to = "Libs.Int") %>%
  ggplot(aes(x = Libs.Int, y = Cr, color = muestra)) + 
    geom_point() + 
    geom_hline(yintercept = int_norm$Cr, lty = 2, col = "gray")


int_mean <- apply(int_norm %>% select(X1:X100), 1, promediar_grupos_aleatorios, n=10) %>% t() %>% data.frame()
int_mean <- cbind(Comp.data, int_mean)
int_mean %>% pivot_longer(X1:X10, values_to = "Libs.Int") %>% 
  ggplot(aes(x = Libs.Int, y = Cr, color = muestra)) + 
    geom_point() + 
    geom_hline(yintercept = int_norm$Cr, lty = 2, col = "gray")


int_mean %>% pivot_longer(X1:X10, values_to = "Libs.Int") %>% 
  ggplot(aes(x = Libs.Int, y = Cr, color = muestra)) + 
    geom_boxplot() + 
    geom_hline(yintercept = int_norm$Cr, lty = 2, col = "gray")

MECHELLE

data.dir <- "Data/mechelle/"
## Mechelle data
L_Mechelle <- map(c("ss406.asc","ss407.asc","ss408.asc","ss409.asc","ss410.asc"), 
                  ~ read_tsv(paste(data.dir,.x,sep = ""), col_names = F, progress = F, show_col_types = F)) 
View(fun.WL.calibration)

L_Mechelle <- L_Mechelle %>% map(~ .x %>% setNames(c("wl",paste("X", 1:(ncol(.x)-1), sep = ""))))
L_Mechelle <- L_Mechelle %>% set_names(c("ss406","ss407","ss408","ss409","ss410"))  

Exploracion Cromo

## elimina shot 1
L_Mechelle <- L_Mechelle %>% 
  map(~ .x %>% .[, c(1, which(Metadata$z != 1) + 1)]) ## elimina disparo #1 (limpieza)

g <- L_Mechelle %>% map(~ data.frame(.x[,1], Int = apply(.x[,2:ncol(.x)], 1, mean))) %>% bind_rows(.id = "id") %>% 
  ggplot(aes(x = wl, y = Int, color = id)) + geom_line() + labs(x = "Wavelength")
g %>% plotly::ggplotly()

Wavelength Calibration

Normalizando por suma total 200-1000

Acumular (z) - Normalizar - Promediar (x)

## acumular
L <- L_Mechelle_new %>% map(~ .x %>% sumar_filas_por_grupos(n = 10))
  
## Normalizar
int <- L %>% map_dfr(fun.int, izq = 267.64, der = 267.74)
factor <- L %>% map_dfr(fun.int, izq = 268.40, der = 268.50)
int_norm <- int/factor

## Promediar
int_norm <- cbind(Comp.data, int_norm)
int_norm %>% pivot_longer(X1:X100, values_to = "Libs.Int") %>% 
    ggplot(aes(x = Libs.Int, y = Cr, color = muestra)) + 
        geom_point()


int_mean <- apply(int_norm %>% select(X1:X100), 1, promediar_grupos_aleatorios, n=10) %>% t() %>% data.frame()
int_mean <- cbind(Comp.data, int_mean)

int_mean %>% pivot_longer(X1:X10, values_to = "Libs.Int") %>% 
  ggplot(aes(x = Libs.Int, y = Cr, color = muestra)) + 
    geom_point() + 
    geom_hline(yintercept = int_norm$Cr, lty = 2, col = "gray")


int_mean %>% pivot_longer(X1:X10, values_to = "Libs.Int") %>% 
  ggplot(aes(x = Libs.Int, y = Cr, color = muestra)) + 
    geom_boxplot() + 
    geom_hline(yintercept = int_norm$Cr, lty = 2, col = "gray")

Normalizar - Acumular (z) - promediar (x)

## Normalizar

int <- L_Mechelle_new %>% map_dfr(fun.int, izq = 267.64, der = 267.74)
factor <- L_Mechelle_new %>% map_dfr(fun.int, izq = 268.40, der = 268.50)
int_norm <- int/factor

## acumular
L <- L_Mechelle_new %>% map(~ .x %>% sumar_filas_por_grupos(n = 10))

## Promediar
int_norm <- cbind(Comp.data, int_norm)
int_norm %>% pivot_longer(X1:X100, values_to = "Libs.Int") %>% ggplot(aes(x = Libs.Int, y = Cr, color = muestra)) + geom_boxplot()

Normalizando por suma total 200-600

Acumular (z) - Normalizar - Promediar (x)

## acumular
L <- L_Mechelle_new %>% map(~ .x %>% sumar_filas_por_grupos(n = 10))
  
## Normalizar
izq = 267.62; der = 267.77
int <- L %>% map_dfr(fun.int, izq = izq, der = der)
factor <- L %>% map_dfr(fun.int, izq = 200, der = 600)
int_norm <- int/factor

## Promediar
int_norm <- cbind(Comp.data, int_norm)
int_norm %>% pivot_longer(X1:X100, values_to = "Libs.Int") %>% ggplot(aes(x = Libs.Int, y = Cr, color = muestra)) + geom_boxplot()

Normalizar - Acumular (z) - promediar (x)

## Normalizar
izq = 267.62; der = 267.77
int <- L_Mechelle_new %>% map_dfr(fun.int, izq = izq, der = der)
factor <- L_Mechelle_new %>% map_dfr(fun.int, izq = 200, der = 600)
int_norm <- int/factor

## acumular
L <- L_Mechelle_new %>% map(~ .x %>% sumar_filas_por_grupos(n = 10))

## Promediar
int_norm <- cbind(Comp.data, int_norm)
int_norm %>% pivot_longer(X1:X100, values_to = "Libs.Int") %>% ggplot(aes(x = Libs.Int, y = Cr, color = muestra)) + geom_boxplot()

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlLCB2ZXJib3NlID0gRikNCnNvdXJjZSgiRnVuY2lvbmVzLlIiKQ0KYGBgDQoNCiMgTGVjdHVyYSBkZSBEYXRvcw0KDQpMbyBkYXRvcyBjb3JyZXNwb25kZSBhIHVuYSBtYXRyaXogNXg1eDEwLiBMYSBtZXRhZGF0YSBzZXLDoSBYID0gMS4uLjI1IHkgWiA9IDEuLi4xMCAocHJvZnVuZGlkYWQpLCBhbWJvcyBkZXRlY3RvcmVzIHRpZW5lbiBsYSBtaXNtYSBtZXRhZGF0YS4NCg0KYGBge3J9DQojI01ldGFkYXRhDQpNZXRhZGF0YSA8LSBkYXRhLmZyYW1lKHggPSByZXAoMToxMDAsIGVhY2ggPSAxMSksIA0KICAgICAgICAgICAgICAgICAgICAgICB6ID0gcmVwKDE6MTEsIDEwMCkpDQoNCkNvbXAuZGF0YSA8LSBkYXRhLmZyYW1lKG11ZXN0cmEgPSBjKCJzczQwNiIsICJzczQwNyIsICJzczQwOCIsICJzczQwOSIsICJzczQxMCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgIEMgPSBjKDAuMTksMC41MCwwLjI4LDAuMTEsMC4zOSksDQogICAgICAgICAgICAgICAgICAgICAgICBNbiA9IGMoMC41MywwLjEzLDAuNjQsMC40OCwwLjQzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIE5pID0gYygxLjY5LDAuNjEsNC41OCwzLjE0LDIuMDQpLA0KICAgICAgICAgICAgICAgICAgICAgICAgQ3IgPSBjKDIuMTIsMy4wMCwwLjA5LDEuMjIsMS43MiksDQogICAgICAgICAgICAgICAgICAgICAgICBNbyA9IGMoMS4wMywwLjgyLDAuMTQsMC43NywwLjQxKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIEN1ID0gYygwLjMyLDAuNDMsMC43MywwLjIzLDAuNDcpKQ0KYGBgDQoNCiMgREVNT04NCg0KYGBge3J9DQpkYXRhLmRpciA8LSAiRGF0YS9kZW1vbi8iDQoNCndsIDwtIHJlYWRfdHN2KHBhc3RlKGRhdGEuZGlyLCJzczQwNi5hc2MiLHNlcCA9ICIiKSwgY29sX25hbWVzID0gRiwgcHJvZ3Jlc3MgPSBGLCBzaG93X2NvbF90eXBlcyA9IEYpICU+JSANCiAgICAgICAgLlssMV0gJT4lIHNldF9uYW1lcygid2wiKSAlPiUgcm93aWRfdG9fY29sdW1uKCkNCg0KIyMgREVNT04gZGF0YQ0KTF9EZW1vbiA8LSBtYXAoYygic3M0MDYuYXNjIiwic3M0MDcuYXNjIiwic3M0MDguYXNjIiwic3M0MDkuYXNjIiwic3M0MTAuYXNjIiksIA0KICAgICAgICAgICAgICAgfiByZWFkX3RzdihwYXN0ZShkYXRhLmRpciwueCxzZXAgPSAiIiksIGNvbF9uYW1lcyA9IEYsIHByb2dyZXNzID0gRiwgc2hvd19jb2xfdHlwZXMgPSBGKSkgDQoNCkxfRGVtb24gPC0gTF9EZW1vbiAlPiUgc2V0X25hbWVzKGMoInNzNDA2Iiwic3M0MDciLCJzczQwOCIsInNzNDA5Iiwic3M0MTAiKSkgIA0KDQpMX0RlbW9uIDwtIExfRGVtb24gJT4lIG1hcCh+IC54ICU+JSBzZXROYW1lcyhjKCJ3bCIscGFzdGUoIlgiLCAxOihuY29sKC54KS0xKSwgc2VwID0gIiIpKSkpDQoNCiMjIGVsaW1pbmEgc2hvdCAxDQpMX0RlbW9uIDwtIExfRGVtb24gJT4lIA0KICBtYXAofiAueCAlPiUgLlssIGMoMSwgd2hpY2goTWV0YWRhdGEkeiAhPSAxKSArIDEpXSkgIyMgZWxpbWluYSBkaXNwYXJvICMxIChsaW1waWV6YSkNCg0KZyA8LSBMX0RlbW9uICU+JSBtYXAofiBkYXRhLmZyYW1lKC54WywxXSwgSW50ID0gYXBwbHkoLnhbLDI6bmNvbCgueCldLCAxLCBtZWFuKSkpICU+JSBiaW5kX3Jvd3MoLmlkID0gImlkIikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB3bCwgeSA9IEludCwgY29sb3IgPSBpZCkpICsgZ2VvbV9saW5lKCkgKyBsYWJzKHggPSAiV2F2ZWxlbmd0aCIpDQpnICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCmBgYA0KDQpgYGB7cn0NCiMjIE5vcm1hbGl6YXINCml6cSA8LSAyNjcuNzANCmRlciA8LSAyNjcuNzUNCmludCA8LSBMX0RlbW9uICU+JSBtYXBfZGZyKGZ1bi5pbnQsIGl6cSA9IGl6cSwgZGVyID0gZGVyKQ0KZmFjdG9yIDwtICAxDQppbnRfbm9ybSA8LSBpbnQvZmFjdG9yDQoNCiMjIGFjdW11bGFyDQppbnRfbm9ybSA8LSBzdW1hcl9maWxhc19wb3JfZ3J1cG9zKGludF9ub3JtLCBuID0gMTAsIHdsID0gRikNCg0KIyMgUHJvbWVkaWFyDQppbnRfbm9ybSA8LSBjYmluZChDb21wLmRhdGEsIGludF9ub3JtKQ0KaW50X25vcm0gJT4lIHBpdm90X2xvbmdlcihYMTpYMTAwLCB2YWx1ZXNfdG8gPSAiTGlicy5JbnQiKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gTGlicy5JbnQsIHkgPSBDciwgY29sb3IgPSBtdWVzdHJhKSkgKyANCiAgICBnZW9tX3BvaW50KCkgKyANCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBpbnRfbm9ybSRDciwgbHR5ID0gMiwgY29sID0gImdyYXkiKQ0KDQppbnRfbWVhbiA8LSBhcHBseShpbnRfbm9ybSAlPiUgc2VsZWN0KFgxOlgxMDApLCAxLCBwcm9tZWRpYXJfZ3J1cG9zX2FsZWF0b3Jpb3MsIG49MTApICU+JSB0KCkgJT4lIGRhdGEuZnJhbWUoKQ0KaW50X21lYW4gPC0gY2JpbmQoQ29tcC5kYXRhLCBpbnRfbWVhbikNCmludF9tZWFuICU+JSBwaXZvdF9sb25nZXIoWDE6WDEwLCB2YWx1ZXNfdG8gPSAiTGlicy5JbnQiKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IExpYnMuSW50LCB5ID0gQ3IsIGNvbG9yID0gbXVlc3RyYSkpICsgDQogICAgZ2VvbV9wb2ludCgpICsgDQogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gaW50X25vcm0kQ3IsIGx0eSA9IDIsIGNvbCA9ICJncmF5IikNCg0KaW50X21lYW4gJT4lIHBpdm90X2xvbmdlcihYMTpYMTAsIHZhbHVlc190byA9ICJMaWJzLkludCIpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gTGlicy5JbnQsIHkgPSBDciwgY29sb3IgPSBtdWVzdHJhKSkgKyANCiAgICBnZW9tX2JveHBsb3QoKSArIA0KICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGludF9ub3JtJENyLCBsdHkgPSAyLCBjb2wgPSAiZ3JheSIpDQoNCmBgYA0KIyBNRUNIRUxMRQ0KDQpgYGB7cn0NCmRhdGEuZGlyIDwtICJEYXRhL21lY2hlbGxlLyINCiMjIE1lY2hlbGxlIGRhdGENCkxfTWVjaGVsbGUgPC0gbWFwKGMoInNzNDA2LmFzYyIsInNzNDA3LmFzYyIsInNzNDA4LmFzYyIsInNzNDA5LmFzYyIsInNzNDEwLmFzYyIpLCANCiAgICAgICAgICAgICAgICAgIH4gcmVhZF90c3YocGFzdGUoZGF0YS5kaXIsLngsc2VwID0gIiIpLCBjb2xfbmFtZXMgPSBGLCBwcm9ncmVzcyA9IEYsIHNob3dfY29sX3R5cGVzID0gRikpIA0KDQpMX01lY2hlbGxlIDwtIExfTWVjaGVsbGUgJT4lIG1hcCh+IC54ICU+JSBzZXROYW1lcyhjKCJ3bCIscGFzdGUoIlgiLCAxOihuY29sKC54KS0xKSwgc2VwID0gIiIpKSkpDQpMX01lY2hlbGxlIDwtIExfTWVjaGVsbGUgJT4lIHNldF9uYW1lcyhjKCJzczQwNiIsInNzNDA3Iiwic3M0MDgiLCJzczQwOSIsInNzNDEwIikpICANCmBgYA0KDQojIyBFeHBsb3JhY2lvbiBDcm9tbw0KDQpgYGB7cn0NCiMjIGVsaW1pbmEgc2hvdCAxDQpMX01lY2hlbGxlIDwtIExfTWVjaGVsbGUgJT4lIA0KICBtYXAofiAueCAlPiUgLlssIGMoMSwgd2hpY2goTWV0YWRhdGEkeiAhPSAxKSArIDEpXSkgIyMgZWxpbWluYSBkaXNwYXJvICMxIChsaW1waWV6YSkNCg0KZyA8LSBMX01lY2hlbGxlICU+JSBtYXAofiBkYXRhLmZyYW1lKC54WywxXSwgSW50ID0gYXBwbHkoLnhbLDI6bmNvbCgueCldLCAxLCBtZWFuKSkpICU+JSBiaW5kX3Jvd3MoLmlkID0gImlkIikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB3bCwgeSA9IEludCwgY29sb3IgPSBpZCkpICsgZ2VvbV9saW5lKCkgKyBsYWJzKHggPSAiV2F2ZWxlbmd0aCIpDQpnICU+JSBwbG90bHk6OmdncGxvdGx5KCkNCmBgYA0KIyMgV2F2ZWxlbmd0aCBDYWxpYnJhdGlvbg0KDQpgYGB7cn0NCnJlZiA8LSA0MzguMzI3NQ0KcCA8LSBkYXRhLmZyYW1lKExfTWVjaGVsbGVbWzFdXVssMV0sIEludCA9IGFwcGx5KExfTWVjaGVsbGVbWzFdXVssMjpuY29sKExfTWVjaGVsbGVbWzFdXSldLCAxLCBtZWFuKSkNCnAkd2wgPC0gcm91bmQocCR3bCw0KQ0KcCA8LSB3aGljaChwJHdsID09IDQzOC4zMjc1KQ0KDQpMX01lY2hlbGxlX25ldyA8LSBMX01lY2hlbGxlICU+JSANCiAgICBtYXAofiBmdW4uV0wuY2FsaWJyYXRpb24ob2xkID0gLngsIHAgPSBwKSkNCg0KTF9NZWNoZWxsZV9uZXcgPC0gTF9NZWNoZWxsZV9uZXcgJT4lIA0KICAgICAgICAgICAgICAgICAgICBtYXAofiAueCAlPiUgZHJvcF9uYSgpICU+JSBmaWx0ZXIoYmV0d2Vlbihyb3dpZCwgMSwgMjY4MTgpKSAlPiUgc2VsZWN0KCFyb3dpZCkpDQoNCg0KZyA8LSBMX01lY2hlbGxlX25ldyAlPiUgcHVycnI6Om1hcCh+IGRhdGEuZnJhbWUod2wgPSAueFssMV0sIEludCA9IGFwcGx5KC54WywyOm5jb2woLngpXSwgMSwgbWVhbikpKSAlPiUgDQogICAgICAgICAgICBiaW5kX3Jvd3MoLmlkID0gImlkIikgJT4lIA0KICAgICAgIGdncGxvdChhZXMoeCA9IHdsLCB5ID0gSW50LCBjb2xvciA9IGlkKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJXYXZlbGVuZ3RoIikNCiANCmcgJT4lIHBsb3RseTo6Z2dwbG90bHkoKQ0KYGBgDQojIyMgTm9ybWFsaXphbmRvIHBvciBzdW1hIHRvdGFsIDIwMC0xMDAwDQoNCkFjdW11bGFyICh6KSAtIE5vcm1hbGl6YXIgLSBQcm9tZWRpYXIgKHgpDQoNCmBgYHtyfQ0KIyMgYWN1bXVsYXINCkwgPC0gTF9NZWNoZWxsZV9uZXcgJT4lIG1hcCh+IC54ICU+JSBzdW1hcl9maWxhc19wb3JfZ3J1cG9zKG4gPSAxMCkpDQogIA0KIyMgTm9ybWFsaXphcg0KaW50IDwtIEwgJT4lIG1hcF9kZnIoZnVuLmludCwgaXpxID0gMjY3LjY0LCBkZXIgPSAyNjcuNzQpDQpmYWN0b3IgPC0gTCAlPiUgbWFwX2RmcihmdW4uaW50LCBpenEgPSAyNjguNDAsIGRlciA9IDI2OC41MCkNCmludF9ub3JtIDwtIGludC9mYWN0b3INCg0KIyMgUHJvbWVkaWFyDQppbnRfbm9ybSA8LSBjYmluZChDb21wLmRhdGEsIGludF9ub3JtKQ0KaW50X25vcm0gJT4lIHBpdm90X2xvbmdlcihYMTpYMTAwLCB2YWx1ZXNfdG8gPSAiTGlicy5JbnQiKSAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gTGlicy5JbnQsIHkgPSBDciwgY29sb3IgPSBtdWVzdHJhKSkgKyANCiAgICAgICAgZ2VvbV9wb2ludCgpDQoNCmludF9tZWFuIDwtIGFwcGx5KGludF9ub3JtICU+JSBzZWxlY3QoWDE6WDEwMCksIDEsIHByb21lZGlhcl9ncnVwb3NfYWxlYXRvcmlvcywgbj0xMCkgJT4lIHQoKSAlPiUgZGF0YS5mcmFtZSgpDQppbnRfbWVhbiA8LSBjYmluZChDb21wLmRhdGEsIGludF9tZWFuKQ0KDQppbnRfbWVhbiAlPiUgcGl2b3RfbG9uZ2VyKFgxOlgxMCwgdmFsdWVzX3RvID0gIkxpYnMuSW50IikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBMaWJzLkludCwgeSA9IENyLCBjb2xvciA9IG11ZXN0cmEpKSArIA0KICAgIGdlb21fcG9pbnQoKSArIA0KICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGludF9ub3JtJENyLCBsdHkgPSAyLCBjb2wgPSAiZ3JheSIpDQoNCmludF9tZWFuICU+JSBwaXZvdF9sb25nZXIoWDE6WDEwLCB2YWx1ZXNfdG8gPSAiTGlicy5JbnQiKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IExpYnMuSW50LCB5ID0gQ3IsIGNvbG9yID0gbXVlc3RyYSkpICsgDQogICAgZ2VvbV9ib3hwbG90KCkgKyANCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBpbnRfbm9ybSRDciwgbHR5ID0gMiwgY29sID0gImdyYXkiKQ0KYGBgDQoNCk5vcm1hbGl6YXIgLSBBY3VtdWxhciAoeikgLSBwcm9tZWRpYXIgKHgpDQoNCmBgYHtyfQ0KIyMgTm9ybWFsaXphcg0KaW50IDwtIExfTWVjaGVsbGVfbmV3ICU+JSBtYXBfZGZyKGZ1bi5pbnQsIGl6cSA9IDI2Ny42NCwgZGVyID0gMjY3Ljc0KQ0KZmFjdG9yIDwtIExfTWVjaGVsbGVfbmV3ICU+JSBtYXBfZGZyKGZ1bi5pbnQsIGl6cSA9IDI2OC40MCwgZGVyID0gMjY4LjUwKQ0KaW50X25vcm0gPC0gaW50L2ZhY3Rvcg0KDQojIyBhY3VtdWxhcg0KTCA8LSBMX01lY2hlbGxlX25ldyAlPiUgbWFwKH4gLnggJT4lIHN1bWFyX2ZpbGFzX3Bvcl9ncnVwb3MobiA9IDEwKSkNCg0KIyMgUHJvbWVkaWFyDQppbnRfbm9ybSA8LSBjYmluZChDb21wLmRhdGEsIGludF9ub3JtKQ0KaW50X25vcm0gJT4lIHBpdm90X2xvbmdlcihYMTpYMTAwLCB2YWx1ZXNfdG8gPSAiTGlicy5JbnQiKSAlPiUgZ2dwbG90KGFlcyh4ID0gTGlicy5JbnQsIHkgPSBDciwgY29sb3IgPSBtdWVzdHJhKSkgKyBnZW9tX2JveHBsb3QoKQ0KYGBgDQoNCiMjIyBOb3JtYWxpemFuZG8gcG9yIHN1bWEgdG90YWwgMjAwLTYwMA0KDQpBY3VtdWxhciAoeikgLSBOb3JtYWxpemFyIC0gUHJvbWVkaWFyICh4KQ0KDQpgYGB7cn0NCiMjIGFjdW11bGFyDQpMIDwtIExfTWVjaGVsbGVfbmV3ICU+JSBtYXAofiAueCAlPiUgc3VtYXJfZmlsYXNfcG9yX2dydXBvcyhuID0gMTApKQ0KICANCiMjIE5vcm1hbGl6YXINCml6cSA9IDI2Ny42MjsgZGVyID0gMjY3Ljc3DQppbnQgPC0gTCAlPiUgbWFwX2RmcihmdW4uaW50LCBpenEgPSBpenEsIGRlciA9IGRlcikNCmZhY3RvciA8LSBMICU+JSBtYXBfZGZyKGZ1bi5pbnQsIGl6cSA9IDIwMCwgZGVyID0gNjAwKQ0KaW50X25vcm0gPC0gaW50L2ZhY3Rvcg0KDQojIyBQcm9tZWRpYXINCmludF9ub3JtIDwtIGNiaW5kKENvbXAuZGF0YSwgaW50X25vcm0pDQppbnRfbm9ybSAlPiUgcGl2b3RfbG9uZ2VyKFgxOlgxMDAsIHZhbHVlc190byA9ICJMaWJzLkludCIpICU+JSBnZ3Bsb3QoYWVzKHggPSBMaWJzLkludCwgeSA9IENyLCBjb2xvciA9IG11ZXN0cmEpKSArIGdlb21fYm94cGxvdCgpDQpgYGANCg0KTm9ybWFsaXphciAtIEFjdW11bGFyICh6KSAtIHByb21lZGlhciAoeCkNCg0KYGBge3J9DQojIyBOb3JtYWxpemFyDQppenEgPSAyNjcuNjI7IGRlciA9IDI2Ny43Nw0KaW50IDwtIExfTWVjaGVsbGVfbmV3ICU+JSBtYXBfZGZyKGZ1bi5pbnQsIGl6cSA9IGl6cSwgZGVyID0gZGVyKQ0KZmFjdG9yIDwtIExfTWVjaGVsbGVfbmV3ICU+JSBtYXBfZGZyKGZ1bi5pbnQsIGl6cSA9IDIwMCwgZGVyID0gNjAwKQ0KaW50X25vcm0gPC0gaW50L2ZhY3Rvcg0KDQojIyBhY3VtdWxhcg0KTCA8LSBMX01lY2hlbGxlX25ldyAlPiUgbWFwKH4gLnggJT4lIHN1bWFyX2ZpbGFzX3Bvcl9ncnVwb3MobiA9IDEwKSkNCg0KIyMgUHJvbWVkaWFyDQppbnRfbm9ybSA8LSBjYmluZChDb21wLmRhdGEsIGludF9ub3JtKQ0KaW50X25vcm0gJT4lIHBpdm90X2xvbmdlcihYMTpYMTAwLCB2YWx1ZXNfdG8gPSAiTGlicy5JbnQiKSAlPiUgZ2dwbG90KGFlcyh4ID0gTGlicy5JbnQsIHkgPSBDciwgY29sb3IgPSBtdWVzdHJhKSkgKyBnZW9tX2JveHBsb3QoKQ0KYGBgDQoNCg0KDQo=